package com.iflytek.uc.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.iflytek.uc.dao.EntityTypeDao;
import com.iflytek.uc.domain.EntityType;
import com.iflytek.uc.domain.EntityType.EntityCategory;
import com.iflytek.uc.domain.Relation.Aggregation;
import com.iflytek.uc.domain.Relation;
import com.iflytek.uc.po.PoEntityType;
import com.iflytek.uc.po.PoRelation;

public class EntityTypeDaoImpl extends HibernateDaoSupport implements
		EntityTypeDao {
	
	private List<EntityType> entityTypes;
	private Map<String, EntityType> map;

	public List<EntityType> getEntityTypes() {
		if (entityTypes == null) {
			initData();
		}
		
		return entityTypes;
	}

	public EntityType getEntityTypeByName(String name) {
		if (map == null) {
			initData();
		}
		
		return map.get(name);
	}
	
	public List<EntityType> getEntityTypesByCategory(EntityCategory category) {
		if (entityTypes == null) {
			initData();
		}
		
		List<EntityType> list = new ArrayList<EntityType>();
		for (EntityType e : entityTypes) {
			if (e.getCategory() == category) {
				list.add(e);
			}
		}
		return list;
	}

	synchronized private void initData() {
		entityTypes = new ArrayList<EntityType>();
		map = new HashMap<String, EntityType>();
		
		String hql = "from PoEntityType order by displayOrder";
		Query query = getSession().createQuery(hql);
		@SuppressWarnings("unchecked")
		List<PoEntityType> list = query.list();
		
		for (PoEntityType e : list) {
			EntityType type = new EntityType();
			type.setCategory(EntityCategory.valueOf(e.getCategory()));
			type.setDisplayName(e.getDisplayName());
			type.setDisplayOrder(e.getDisplayOrder());
			type.setIcon16(e.getIcon16());
			type.setName(e.getName());
			type.setProtected(e.getProtected());
			
			entityTypes.add(type);
			map.put(type.getName(), type);
		}
	}

	public List<Relation> getParentRelations(String name) {
		String hql = "from PoRelation where childTypeName=:name";
		Query query = getSession().createQuery(hql);
		query.setString("name", name);
		@SuppressWarnings("unchecked")
		List<PoRelation> list = query.list();
		return convertRelations(list);
	}

	public List<Relation> getChildRelations(String name) {
		String hql = "from PoRelation where parentTypeName=:name";
		Query query = getSession().createQuery(hql);
		query.setString("name", name);
		@SuppressWarnings("unchecked")
		List<PoRelation> list = query.list();
		return convertRelations(list);
	}

	private Relation convertRelation(PoRelation r) {
		if (r == null) {
			return null;
		}
		
		Relation relation = new Relation();
		relation.setAggregation(Aggregation.valueOf(r.getAggregation()));
		relation.setChild(getEntityTypeByName(r.getChildTypeName()));
		relation.setParent(getEntityTypeByName(r.getParentTypeName()));
		
		return relation;
	}

	private List<Relation> convertRelations(List<PoRelation> list) {
		List<Relation> r = new ArrayList<Relation>();
		for (PoRelation e : list) {
			r.add(convertRelation(e));
		}
		return r;
	}
}
